package cn.itsource.user.service.impl;

import cn.itsource.basic.basic.domain.dto.EmailDto;
import cn.itsource.basic.basic.domain.dto.SendSmsDto;
import cn.itsource.basic.exception.CustomException;
import cn.itsource.basic.utils.MD5Utils;
import cn.itsource.basic.utils.StrUtils;
import cn.itsource.user.domain.Logininfo;
import cn.itsource.user.domain.User;
import cn.itsource.user.mapper.LogininfoMapper;
import cn.itsource.user.mapper.UserMapper;
import cn.itsource.user.service.IUserService;
import cn.itsource.basic.basic.service.impl.IBaseServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.Date;

@Service
@Transactional
public class UserServiceImpl extends IBaseServiceImpl<User> implements IUserService {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private LogininfoMapper logininfoMapper;

    @Override
    public void phoneRegister(SendSmsDto dto) {
        //1.检验空值
        if(StringUtils.isEmpty(dto.getMobile()) || StringUtils.isEmpty(dto.getPassword())
        || StringUtils.isEmpty(dto.getConfirmPassword())){
            throw new CustomException("密码、电话不得为空!");
        }
        //2.检验密码是否一致
        if(!(dto.getPassword()).equals(dto.getConfirmPassword())){
            throw new CustomException("两次输入的密码不一致!");
        }
        //3.根据前端传递的手机号去拼接业务键后，再去redis中查询
        String smsCodeKey = dto.getMobile()+":register";
        Object smsCodeValue= redisTemplate.opsForValue().get(smsCodeKey);
        //4.1.如果查不到，就抛出自定义异常，验证码过期
        if (smsCodeValue == null){
            throw new CustomException("短信验证码已经过期");
        }
        //4.2.查到就和前端的验证码做对比
        String smsCode  = smsCodeValue.toString().split(":")[0];
        if(!smsCode.equals(dto.getSmsCode())){
            throw new CustomException("短信验证码输入错误");
        }
        //5.生成盐值，32位随机数
        String salt = StrUtils.getComplexRandomString(32);
        //6.使用MD5工具加密密码，密码需要和盐值拼接在一起加密
        String md5PassWord = MD5Utils.encrypByMd5(dto.getPassword() + salt);
        //7.构建User和Logininfo的参数对象，初始化参数
        User user = initUser(dto.getMobile(),salt,md5PassWord);

        Logininfo logininfo = user2LoginInfo(user);
        //8.先保存Logininfo，获取自增id
        logininfoMapper.insert(logininfo);
        //9.把Logininfo保存后的自增id给user
        user.setId(logininfo.getId());
        //10.再保存User
        userMapper.insert(user);
    }

    @Override
    public void emailRegister(EmailDto dto) {
        //1.检验空值
        if(StringUtils.isEmpty(dto.getEmail())){
            throw new CustomException("QQ不得为空!");
        }
        //2.检验密码是否一致
        if(!(dto.getPassword()).equals(dto.getConfirmPassword())){
            throw new CustomException("两次输入的密码不一致!");
        }
        //3.根据前端传递的手机号去拼接业务键后，再去redis中查询
        String smsCodeKey = dto.getEmail()+":register";
        Object smsCodeValue= redisTemplate.opsForValue().get(smsCodeKey);

        //4.1.如果查不到，就抛出自定义异常，验证码过期
        if (smsCodeValue == null){
            throw new CustomException("QQ验证码已经过期");
        }
        //4.2.查到就和前端的验证码做对比
        String smsCode  = smsCodeValue.toString().split(":")[0];
        if(!smsCode.equals(dto.getSmsCode())){
            throw new CustomException("QQ验证码输入错误");
        }
        //5.生成盐值，32位随机数
        String salt = StrUtils.getComplexRandomString(32);
        //6.使用MD5工具加密密码，密码需要和盐值拼接在一起加密
        String md5PassWord = MD5Utils.encrypByMd5(dto.getPassword() + salt);

        //7.构建User和Logininfo的参数对象，初始化参数
        User user = initUser(dto.getEmail(),salt,md5PassWord);
        Logininfo logininfo = user2LoginInfo(user);
        //8.先保存Logininfo，获取自增id
        logininfoMapper.insert(logininfo);
        //9.把Logininfo保存后的自增id给user
        user.setId(logininfo.getId());
        //10.再保存User
        userMapper.insert(user);

    }

    private Logininfo user2LoginInfo(User user) {
        Logininfo logininfo = new Logininfo();
        //这个工具是Spring提供的
        BeanUtils.copyProperties(user,logininfo);
        //初始化参数type 1主站用户
        logininfo.setType(1);
        //初始化参数disabl 1 可用
        logininfo.setDisable(1);
        return logininfo;
    }

    private User initUser(String mobile, String salt, String md5PassWord) {
        User user = new User();
        user.setUsername(mobile);
        user.setPhone(mobile);
        user.setSalt(salt);
        user.setPassword(md5PassWord);
        user.setState(1);
        user.setCreatetime(new Date());
        return user;
    }

}
